﻿using System;

using System.Net.NetworkInformation;
using System.Collections.Generic;

namespace OpenLightGroup.Common.ApplicationServices
{
    internal class NetworkDelegateManager
    {
        private static NetworkDelegateManager _instance = new NetworkDelegateManager();

        private List<Action> _networkLostActions = new List<Action>();
        private List<Action> _networkRestoredActions = new List<Action>();
        private bool? _lastCheckResult = null;


        private NetworkDelegateManager()
        {

            NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);
        }

        internal static void RegisterDelegates(Action OnNetworkRestored, Action OnNetworkLost)
        {

            if (OnNetworkLost != null)
                _instance._networkLostActions.Add(OnNetworkLost);

            if (OnNetworkRestored != null)
                _instance._networkRestoredActions.Add(OnNetworkRestored);

        }

        internal static void UnregisterDelegates(Action OnNetworkRestored, Action OnNetworkLost)
        {

            if (_instance._networkLostActions != null && _instance._networkLostActions.Contains(OnNetworkLost))
            {
                _instance._networkLostActions.Remove(OnNetworkLost);
            }

            if (_instance._networkRestoredActions != null && _instance._networkRestoredActions.Contains(OnNetworkRestored))
            {
                _instance._networkRestoredActions.Remove(OnNetworkRestored);
            }
     
        }
        internal static void ForceNetworkCheck()
        {
            bool currentlyAvailable = NetworkInterface.GetIsNetworkAvailable();

            //If the network is currently up and it was down at last check
            if (currentlyAvailable == true
                && (_instance._lastCheckResult.HasValue && _instance._lastCheckResult.Value == false))
            {

                foreach (var item in _instance._networkRestoredActions)
                {
                    if (item != null)
                        item.Invoke();
                }

            }
            //If the network is currently down and it was up at last check
            else if (currentlyAvailable == false
                && (_instance._lastCheckResult.HasValue && _instance._lastCheckResult.Value == true))
            {
                foreach (var item in _instance._networkLostActions)
                {
                    if (item != null)
                        item.Invoke();
                }

            }

            _instance._lastCheckResult = currentlyAvailable;
        }

       private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
        {
            ForceNetworkCheck();
        }

    }
}
